/**
 * 接口仅仅是trait (特质)的一个功能
 * 
 * rust的接口特质比java的接口更加灵活，体现在：
 * 1.由于实现的方式（可以和结构等不在一个文件），所以可以根据需要在任意地方定义并实现接口特质
 * 2.当然，这样可能会有一些重复定义的情况，或者是不好管理的问题。
 * 3.此外还存在一个问题：不同模块实现的不同特质是否不同？
 * //TODO:: 需要基于模块实现不同的特质，以便验证这种问题
 * 
 * 根据 trpl书籍的说法：不能为外部类型实现外部 trait  。孤儿规则？
 * 
 */
trait Summary {
    fn summarize(&self) -> String;
    fn get_content(&self) -> &String;
    fn is_empty(&self) -> bool {
        self.get_content().is_empty()
    }
}
struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({}) \n {}", self.headline, self.author, self.location,self.content)
    }
    fn get_content(&self) -> &String {
        &self.content
    }
    fn is_empty(&self) -> bool {
        println!("{}", self.content.len());
        self.content.len()<1000
    }
}

fn print(article:&impl Summary){
    println!("使用impl trait的方式:{}", article.get_content());
}
/**
 * 使用<T:t>的方式，是impl trait的方式的正规形式。  
 * 即print_normal是print的正规形式
 */
fn print_normal<T:Summary>(article:&T){
    println!("使用<T:t>的方式：{}", article.get_content());
}

fn main(){
    let news= NewsArticle {
        headline: String::from("英雄纪念碑"),
        location: String::from("中国北京"),
        author: String::from("新华社记者毛泽东"),
        content: String::from("由此上溯到一千八百四十年，从那时起，为了反对内外敌人，
        争取民族独立和人民自由幸福，在历次斗争中牺牲的人民英雄们永垂不朽！")
    };
    println!("{}", news.summarize());
    println!("{}", news.is_empty());    
    print(&news);
    print_normal(&news);
}